package com.demo.socket.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * @author wangning
 * @date 2023/10/31 11:52
 */
public class TcpServer {
    ServerSocket serverSocket = null;

    // 定义构造方法 , 为服务器设置一个端口号
    public TcpServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器已启动!");
        // 因为服务器要处理多个客户端的请求 , 套上一个循环
        while (true) {
            Socket clientSocket = serverSocket.accept();
            processConnection(clientSocket);
        }
    }

    private static void processConnection(Socket clientSocket) {
        try (InputStream inputStream = clientSocket.getInputStream();
             OutputStream outputStream = clientSocket.getOutputStream()) {
            // 方便对字节流进行读写操作 创建 Scanner 和 PrintWriter
            Scanner scannerFromSocket = new Scanner(inputStream);
            PrintWriter printWriter = new PrintWriter(outputStream);

            while (true) {
                // 1. 读取请求
                if (!scannerFromSocket.hasNext()) {
                    // 证明读取到流的末尾了  (对端的客户端已经关闭了)
                    System.out.printf("[%s : %d] 客户端已经下线! \n", clientSocket.getInetAddress().toString(), clientSocket.getPort());
                    break;
                }
                // 通过scannerFromSocket 对象来读取请求
                String request = scannerFromSocket.nextLine();
                // 处理请求
                String response = process(request);
                // 将请求写回客户端
                // 注意在这里写回的时候 使用的println 自带的换行操作
                printWriter.println(response);
                // 重点 : 刷新缓冲区
                printWriter.flush();
                System.out.printf("[%s : %d] req: %s; resp : %s \n", clientSocket.getInetAddress().toString(), clientSocket.getPort(),
                        request, response);

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 断开连接后一定要去关闭文件 .
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 由于这里是回显服务 , 所以直接返回这个原请求就可以了
    private static String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpServer tcpEchoServer = new TcpServer(9090);
        tcpEchoServer.start();
    }
}
